﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using StockholmsStad.Web.UI.Class.Interfaces;
using StockholmsStad.Web.UI.Class.Model;
using StockholmsStad.Web.UI.Class.Utilities;
using StockholmsStad.Web.UI.UIServiceReference;

namespace StockholmsStad.Web.UI.Test
{
    /// <summary>
    ///This is a test class for BookingModelTest and is intended
    ///to contain all BookingModelTest Unit Tests
    ///</summary>
    [TestClass()]
    public class BookingModelTest
    {
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }

        #region Additional test attributes

        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //

        #endregion

        /// <summary>
        ///A test for FreeTimeblocks
        ///</summary>
        [TestMethod()]
        public void FreeTimeblocksTest()
        {
            var mocks = new MockRepository();
            ISession session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var facade = mocks.StrictMock<IServiceFacade>();
            var target = new BookingModel(session, facade);
            var firstDateTime = new DateTime(1970, 01, 01, 12, 23, 45);
            // Expect
            Expect.Call(facade.GetFreeTimeblocks(null)).Return(new TimeBlock[]
                                                                   {
                                                                       new TimeBlock {StartDateTime = firstDateTime}
                                                                       ,
                                                                       new TimeBlock
                                                                           {
                                                                               StartDateTime =
                                                                                   new DateTime(1970, 01, 02, 12, 23, 45),
                                                                           },
                                                                   });
            // Replay
            mocks.ReplayAll();
            IList<TimeBlock> timeBlocks = target.GetFreeTimeblocks(null);
            Assert.AreEqual(2, timeBlocks.Count());
            Assert.AreEqual(firstDateTime, timeBlocks.First().StartDateTime);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for CeremonyTypes
        ///</summary>
        [TestMethod()]
        public void CeremonyTypesTest()
        {
            var mocks = new MockRepository();
            ISession session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var facade = mocks.StrictMock<IServiceFacade>();
            var target = new BookingModel(session, facade);
            // Expect
            Expect.Call(facade.CeremonyTypes).Return(new List<ValueIdPair>
                                                         {
                                                             new ValueIdPair
                                                                 {
                                                                     Name = CeremonyType.Ordinary.ToString(),
                                                                     Id = (int) CeremonyType.Ordinary
                                                                 },
                                                             new ValueIdPair
                                                                 {
                                                                     Name = CeremonyType.Individual.ToString(),
                                                                     Id = (int) CeremonyType.Individual
                                                                 },
                                                         });
            // Replay
            mocks.ReplayAll();
            IList<ValueIdPair> actual = target.CeremonyTypes;
            Assert.AreEqual(2, actual.Count());
            Assert.AreEqual(CeremonyType.Ordinary.ToString(), actual.First().Name);
            Assert.AreEqual((int) CeremonyType.Ordinary, actual.First().Id);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for CachedFreeTimeblocks
        ///</summary>
        [TestMethod()]
        public void CachedFreeTimeblocksTest()
        {
            var mocks = new MockRepository();
            ISession session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var facade = mocks.StrictMock<IServiceFacade>();
            var target = new BookingModel(session, facade);
            var firstDateTime = new DateTime(1970, 01, 01, 12, 23, 45);
            mocks.ReplayAll();
            target.CachedFreeTimeblocks = new List<DateTime>
                                              {
                                                  new DateTime(1970, 01, 02, 12, 23, 45),
                                                  firstDateTime,
                                                  new DateTime(1970, 01, 03, 12, 23, 45)
                                              }.OrderBy(d => d.Ticks);
            IOrderedEnumerable<DateTime> actual = target.CachedFreeTimeblocks;
            Assert.AreEqual(3, actual.Count());
            Assert.AreEqual(firstDateTime, actual.First());
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for CachedBookedTimeblocks
        ///</summary>
        [TestMethod()]
        public void CachedBookedTimeblocksTest()
        {
            var mocks = new MockRepository();
            ISession session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var facade = mocks.StrictMock<IServiceFacade>();
            var target = new BookingModel(session, facade);
            var firstDateTime = new DateTime(1970, 01, 01, 12, 23, 45);
            mocks.ReplayAll();
            target.CachedBookedTimeblocks = new List<DateTime>
                                                {
                                                    new DateTime(1970, 01, 02, 12, 23, 45),
                                                    firstDateTime,
                                                    new DateTime(1970, 01, 03, 12, 23, 45)
                                                }.OrderBy(d => d.Ticks);
            IOrderedEnumerable<DateTime> actual = target.CachedBookedTimeblocks;
            Assert.AreEqual(3, actual.Count());
            Assert.AreEqual(firstDateTime, actual.First());
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for BookedTimeblocks
        ///</summary>
        [TestMethod()]
        public void BookedTimeblocksTest()
        {
            var mocks = new MockRepository();
            ISession session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var facade = mocks.StrictMock<IServiceFacade>();
            var target = new BookingModel(session, facade);
            var firstDateTime = new DateTime(1970, 01, 01, 12, 23, 45);
            //Expect
            Expect.Call(facade.GetBookedTimeblocks(null)).Return(new TimeBlock[]
                                                                     {
                                                                         new TimeBlock
                                                                             {
                                                                                 StartDateTime = firstDateTime,
                                                                             },
                                                                         new TimeBlock
                                                                             {
                                                                                 StartDateTime =
                                                                                     new DateTime(1970, 01, 02, 12, 23,
                                                                                                  45),
                                                                             }
                                                                         ,
                                                                     });
            // Replay
            mocks.ReplayAll();
            IList<TimeBlock> timeBlocks = target.GetBookedTimeblocks(null);
            Assert.AreEqual(2, timeBlocks.Count());
            Assert.AreEqual(firstDateTime, timeBlocks.First().StartDateTime);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for RegisterBooking
        ///</summary>
        [TestMethod()]
        public void RegisterBookingTest()
        {
            var mocks = new MockRepository();
            ISession session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var facade = mocks.StrictMock<IServiceFacade>();
            var target = new BookingModel(session, facade);
            Booking booking = Booking.createOrdinaryBooking(null, null, null);
            target.Booking = booking;
            User user = new User {CoupleId = 42};
            Expect.Call(() => facade.RegisterBooking(user, booking));
            // Eftersom target.User kontrolleras med assert
            mocks.ReplayAll();
            target.RegisterBooking(user);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for Booking
        ///</summary>
        [TestMethod()]
        public void BookingTest()
        {
            ISession session = new DictionarySessionAdapter(new Dictionary<string, object>());
            const IServiceFacade facade = null;
            var mocks = new MockRepository();
            mocks.ReplayAll();
            var target = new BookingModel(session, facade);
            Booking booking = Booking.createIndividualBooking("2007-01-01", "sdfsdf");
            target.Booking = booking;
            Booking actual = target.Booking;
            Assert.AreSame(booking, actual);
            Assert.AreEqual(booking.BookingCode, actual.BookingCode);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for GetLocationName
        ///</summary>
        [TestMethod()]
        public void GetLocationNameTest()
        {
            var mocks = new MockRepository();
            ISession session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var facade = mocks.StrictMock<IServiceFacade>();
            var target = new BookingModel(session, facade);
            string locationName = target.GetLocationName((int) CeremonyType.Ordinary);
            Assert.AreEqual("Stadshuset", locationName);
            mocks.ReplayAll();
            locationName = target.GetLocationName((int) CeremonyType.Individual);
            Assert.AreEqual("Annan plats", locationName);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for BookingModel Constructor
        ///</summary>
        [TestMethod()]
        public void BookingModelConstructorTest()
        {
            var mocks = new MockRepository();
            ISession session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var facade = mocks.StrictMock<IServiceFacade>();
            mocks.ReplayAll();
            var target = new BookingModel(session, facade);
            Assert.IsNotNull(target);
            mocks.VerifyAll();
        }
    }
}